import os

# Browser views
from Products.Five.browser import BrowserView
from Products.CMFPlone.utils import getToolByName
from Products.CMFPlone import Batch
from plone.app.layout.navigation.navtree import buildFolderTree

from apkn.workspaces import workspacesMessageFactory as _
from apkn.workspaces.browser.config import DEFAULT_WORKSPACE_TYPES, \
                                           WORKSPACE_SEARCH_FILTERS
from apkn.workspaces.interfaces import IWorkSpace
from apkn.workspaces import LOG

#address book interfaces
ADDRESS_BOOK_IIS = None
try:
    from collective.contacts.interfaces import IAddressBook, IPerson,\
                                               IGroup, IOrganization
    ADDRESS_BOOK_IIS = [IAddressBook, IPerson, IGroup, IOrganization]
    ADDRESS_BOOK_IIS = [ii.__identifier__ for ii in ADDRESS_BOOK_IIS]
except ImportError:
    LOG.error('Unable to import address type interfaces. Please check that collective.contacts is installed.')

# --- GLOBALS

DEFAULT_BATCH_SIZE = 10
BATCH_START_STRING = 'start'
DEFAULT_SLICE = 'recent-items'
ADDRESS_LOOKUP_PATH_KEY = 'address_lookup_path'

# --- Catalog Filter
WORKSPACE_ITEMS = [
                    { 
                    'type':DEFAULT_WORKSPACE_TYPES, 
                    'title':_('Recent Items'), 
                    'type_id': 'recent-items',
                    'extra_params': {'sort_on':'Date',
                                     'sort_order':'descending'
                                    }
                    },
                    { 'type':'Blog Entry', 'title':_('Blog Posts'), 'type_id': 'blog'},
                    { 'type':'Event', 'title':_('Events'), 'type_id': 'event'},
                    { 'type':'Document', 'title':_('Pages'), 'type_id': 'document'},
                    { 'type':'File', 'title':_('Files'), 'type_id': 'file'},
                    { 'type':'Video', 'title':_('Videos'), 'type_id': 'video'},
                    { 'type':'Image', 'title':_('Images'), 'type_id': 'image'},
                    { 'type':'Link', 'title':_('Bookmarks'), 'type_id': 'link'},
                  ]

class HomeView(BrowserView):
    '''
    Renders pretty interface for workspace content
    '''
    
    def __call__(self):
        # $$ set default slice because we mess with the request later
        # $$ allows us to get the correct tab to activate and correct
        # batch to slice
        self.current_slice = self.request.form.get('slice',
                                              DEFAULT_SLICE)
        return self.index()

    @property
    def workspace_searchable_types(self):
        return DEFAULT_WORKSPACE_TYPES

    @property
    def portal_catalog(self):
        return getToolByName(self.context, 'portal_catalog', None)

    @property
    def catalog_path(self):
        return '/'.join(self.context.getPhysicalPath())

    def extendRequestForm(self, slice=DEFAULT_SLICE):
        self.request.form['slice'] = slice
        return


    def homeViewItems(self):
        '''
        returns a list of categorized catalog items
        ** should be cached
        '''
        ws_results = []
        for ws_item in WORKSPACE_ITEMS:
            ws_dict = ws_item
            query_params = ws_item.get('extra_params', {})
            query_params['portal_type'] = ws_item['type']
            query_result = self.batchResults(query_params,
                                            ws_dict.get('type_id'))
            ws_dict['catalog_items'] = query_result
            ws_dict['is_selected'] = \
                            (self.current_slice == ws_dict['type_id'])
            ws_results.append(ws_dict)
             
        return ws_results

    def batchResults(self, query, slice):
        catalog_results = self.processQuery(query)
        start = 0
        if slice == self.current_slice:
            start = self.request.get(BATCH_START_STRING, 0)
        return Batch(catalog_results, 
                     DEFAULT_BATCH_SIZE, 
                     int(start), 
                     orphan=1,
                     b_start_str = BATCH_START_STRING,
                     quantumleap = 0)

    def processQuery(self, catalog_params = {}):
        '''
        Returns a list of catalog items (brains)
        TODO: memoize for 10 minutes or so
        '''
        if self.portal_catalog is not None:
            query = dict(
                path = dict(query = self.catalog_path, depth = 1),
            )
            for key,value in catalog_params.items():
                query[key] = value
            catalog_results = self.portal_catalog(query)
            if not len(catalog_results):
                # ** go deeper
                query['path'] = dict(query = self.catalog_path)
                catalog_results = self.portal_catalog(query)
            return catalog_results
        else:
            LOG.error("Unable to acquire portal_catalog in context")
            return []
        

class SearchView(HomeView):
    
    @property
    def search_terms(self):
        return self.request.form.get('search_query',
         '')

    def search_message(self):
        s_message = u''
        if self.search_terms:
            s_message = _('Seach results for : $terms ',
                         mapping = {'terms': self.search_terms})
        return s_message
        
    def searchViewItems(self):
        return self.batchResults(self.buildQuery(), DEFAULT_SLICE)
    
    def buildQuery(self):
        query = dict(
            path = dict(path = self.catalog_path),
            SearchableText = self.request.form.get('search_query',''),
            )
        for filter in WORKSPACE_SEARCH_FILTERS:
            q_param = filter.get('identity')
            q_value = self.request.form.get(q_param, '')
            if q_value:
                query[q_param] = q_value
        return query


class ContactsView(BrowserView):

    @property
    def query(self):
        if ADDRESS_BOOK_IIS is not None:
            query = dict(path = self.lookup_root,
                         object_provides = ADDRESS_BOOK_IIS)
            return query
        else:
            return None

    @property
    def address_path_set(self):
        return ADDRESS_LOOKUP_PATH_KEY in os.environ.keys()

    @property
    def lookup_root(self):
        if self.address_path_set:
            return os.environ.get(ADDRESS_LOOKUP_PATH_KEY)
        portal_url = getToolByName(self.context, 'portal_url', None)
        if portal_url is not None:
            return portal_url.getPortalPath()
        else:
            LOG.error('Unable to anchor to site root')
            return '/'

    def get_contacts(self):
        if self.query is not None:
            return buildFolderTree(self.context, None, self.query)
        return []
    

class PublicView(HomeView):

    @property
    def portal_url_tool(self):
        return getToolByName(self.context, 'portal_url', None)

    @property
    def catalog_path(self):
        search_path = '/'
        if self.portal_catalog:
            # get the first item in catalog
            try:
                base_url = self.portal_url_tool.getPortalPath()
                wspace_query = { 'object_provides': IWorkSpace.__identifier__,
                                 'path': dict(query = base_url,
                                                depth = 1)
                                }
                found_spaces = self.portal_catalog(wspace_query)
                if len(found_spaces):
                    # root search to first workspace result
                    search_path = found_spaces[0].getPath()
                    LOG.debug('Searching path :@ %s', search_path)
            except:
                LOG.error('Failed to load workspace path @@ using /')
        return search_path

    @property
    def is_anonymous(self):
        is_anon = True
        member_tool = getToolByName(self.context, 'portal_membership', 
                                    None)
        if member_tool is not None:
            return member_tool.isAnonymousUser()
        return is_anon


    def processQuery(self, catalog_params = {}):
        '''
        Returns a list of catalog items (brains)
        TODO: memoize for 10 minutes or so
        '''
        if self.portal_catalog is not None:
            query = dict(
                path = dict(query = self.catalog_path, depth = 1),
            )
            for key,value in catalog_params.items():
                query[key] = value
            if self.is_anonymous:
                query['review_state'] = 'publishedanonymous'
            catalog_results = self.portal_catalog(query)
            if not len(catalog_results):
                # ** go deeper
                query['path'] = dict(query = self.catalog_path)
                catalog_results = self.portal_catalog(query)
            return catalog_results
        else:
            LOG.error("Unable to acquire portal_catalog in context")
            return []

